WITH
  stream AS (
    <%= if stream_id do %>
      UPDATE "<%= schema %>".streams
      SET stream_version = stream_version + $2::bigint
      WHERE stream_id = $1::bigint
      returning stream_id, stream_version - $2::bigint as initial_stream_version
    <% else %>
      INSERT INTO "<%= schema %>".streams (stream_uuid, stream_version)
      VALUES ($1, $2::bigint)
      returning stream_id, stream_version - $2::bigint as initial_stream_version
    <% end %>
  ),
  new_events_indexes (event_id, index, stream_version) AS (
    VALUES
    <%= for i <- 0..(number_of_events - 1) do %>
      <%= unless i == 0 do %>,<% end %>
      ($<%= i*9+3 %>::uuid, $<%= i*9+10 %>::int, $<%= i*9+11 %>::bigint)
    <% end %>
  ),
  events AS (
    INSERT INTO "<%= schema %>".events
      (
        event_id,
        event_type,
        causation_id,
        correlation_id,
        data,
        metadata,
        created_at
      )
    VALUES
    <%= for i <- 0..(number_of_events - 1) do %>
      <%= unless i == 0 do %>,<% end %>
      ($<%= i*9+3 %>, $<%= i*9+4 %>, $<%= i*9+5 %>, $<%= i*9+6 %>, $<%= i*9+7 %>, $<%= i*9+8 %>, $<%= i*9+9 %>)
    <% end %>
  ),
  source_stream_events AS (
    INSERT INTO "<%= schema %>".stream_events
      (
        event_id,
        stream_id,
        stream_version,
        original_stream_id,
        original_stream_version
      )
    SELECT
      new_events_indexes.event_id,
      stream.stream_id,
      stream.initial_stream_version + new_events_indexes.index,
      stream.stream_id,
      stream.initial_stream_version + new_events_indexes.index
    FROM new_events_indexes, stream
  ),
  linked_stream AS (
    UPDATE "<%= schema %>".streams
    SET stream_version = stream_version + $2::bigint
    WHERE stream_id = 0
    RETURNING stream_version - $2::bigint as initial_stream_version
  )
INSERT INTO "<%= schema %>".stream_events
(
  event_id,
  stream_id,
  stream_version,
  original_stream_id,
  original_stream_version
)
SELECT
  new_events_indexes.event_id,
  0,
  linked_stream.initial_stream_version + new_events_indexes.index,
  stream.stream_id,
  stream.initial_stream_version + new_events_indexes.index
FROM
  new_events_indexes, linked_stream, stream;
